package org.chen.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.auth.oauth2.ServiceAccountCredentials;
import com.google.cloud.translate.Translate;
import com.google.cloud.translate.TranslateOptions;
import com.google.cloud.translate.Translation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.StringEscapeUtils;
import org.chen.common.exception.ServiceException;
import org.chen.common.utils.SnowflakeIdGenerator;
import org.chen.domain.dto.SingleTranslateDTO;
import org.chen.domain.entity.ArticleTranslation;
import org.chen.domain.entity.VideoArticle;
import org.chen.domain.vo.ArticleTranslationVO;
import org.chen.domain.vo.ArticleVO;
import org.chen.domain.vo.BatchTranslationResultVO;
import org.chen.mapper.ArticleMapper;
import org.chen.mapper.ArticleTranslationMapper;
import org.chen.service.TranslationService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.io.FileInputStream;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class GoogleTranslationServiceImpl extends ServiceImpl<ArticleTranslationMapper, ArticleTranslation> implements TranslationService {

    @Value("${google.cloud.projectId}")
    private String projectId;

    @Autowired
    private ArticleTranslationMapper translationMapper;

    @Autowired
    private ArticleMapper articleMapper;

    // 支持的语言配置
    private static final Map<String, Map<String, String>> SUPPORTED_LANGUAGES = new HashMap<>();

    static {
        addLanguage("en", "英语", "English");
        addLanguage("vi", "越南语", "Tiếng Việt");
        addLanguage("id", "印尼语", "Bahasa Indonesia");
        addLanguage("hi", "印地语", "हिन्दी");
        addLanguage("th", "泰语", "ไทย");
        addLanguage("ur", "乌尔都语", "اردو");
        addLanguage("ar", "阿拉伯语", "العربية");
        addLanguage("ms", "马来语", "Bahasa Melayu");
        addLanguage("pt", "葡萄牙语", "Português");
        addLanguage("zh", "中文简体", "中文");
    }

    private static void addLanguage(String code, String name, String nativeName) {
        Map<String, String> langInfo = new HashMap<>();
        langInfo.put("name", name);
        langInfo.put("nativeName", nativeName);
        SUPPORTED_LANGUAGES.put(code, langInfo);
    }

    @Override
    public Map<String, Map<String, String>> getSupportedLanguages() {
        return SUPPORTED_LANGUAGES;
    }

    /**
     * 获取翻译服务
     */
    private Translate getTranslateService() {
        // 使用服务账号方式授权（更安全）
        try {
            GoogleCredentials credentials = GoogleCredentials.fromStream(
                    new FileInputStream("D:\\Users\\LT08\\Desktop\\video-cloud\\video-7040\\src\\main\\resources\\disco-math-452003-q3-5bc90ed22cba.json"));
            return TranslateOptions.newBuilder()
                    .setProjectId(projectId)
                    .setCredentials(credentials)
                    .build()
                    .getService();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 清理翻译结果，移除HTML实体编码
     */
    private String cleanTranslatedText(String text) {
        if (StringUtils.isBlank(text)) {
            return text;
        }

        // 解码HTML实体
        String decoded = StringEscapeUtils.unescapeHtml4(text);

        // 额外处理特定的HTML实体，确保完全解码
        decoded = decoded.replace("&#39;", "'")
                .replace("&quot;", "\"")
                .replace("&amp;", "&")
                .replace("&lt;", "<")
                .replace("&gt;", ">");

        return decoded;
    }

    @Override
    public String translate(String text, String targetLanguage) {
        if (StringUtils.isBlank(text)) {
            return "";
        }

        // 获取翻译服务
        Translate translate = getTranslateService();

        // 执行翻译
        Translation translation = translate.translate(
                text,
                Translate.TranslateOption.targetLanguage(targetLanguage)
        );

        // 清理并返回翻译结果
        return cleanTranslatedText(translation.getTranslatedText());
    }

    @Override
    public ArticleVO translateArticle(String id, String targetLanguage) {
        // 检查文章是否存在
        VideoArticle article = articleMapper.selectById(id);
        if (article == null) {
            throw new ServiceException("文章不存在");
        }

        // 先检查是否已有翻译
        ArticleTranslation existingTranslation = translationMapper.selectByArticleAndLanguage(id, targetLanguage);

        // 如果已存在翻译，则直接返回
        if (existingTranslation != null) {
            ArticleVO vo = convertToVO(article);
            vo.setTranslatedTitle(existingTranslation.getTitle());
            vo.setTranslatedDescription(existingTranslation.getDescription());
            vo.setTargetLanguage(targetLanguage);
            return vo;
        }

        // 调用翻译服务
        try {
            // 翻译标题
            String translatedTitle = translate(article.getTitle(), targetLanguage);

            // 翻译描述
            String translatedDescription = null;
            if (StringUtils.isNotBlank(article.getDescription())) {
                translatedDescription = translate(article.getDescription(), targetLanguage);
            }

            // 保存翻译结果
            saveOrUpdateTranslation(id, targetLanguage, translatedTitle, translatedDescription);

            // 返回结果
            ArticleVO vo = convertToVO(article);
            vo.setTranslatedTitle(translatedTitle);
            vo.setTranslatedDescription(translatedDescription);
            vo.setTargetLanguage(targetLanguage);
            return vo;
        } catch (Exception e) {
            log.error("Translation failed for article {}", id, e);
            throw new ServiceException("翻译失败: " + e.getMessage());
        }
    }

    @Override
    public BatchTranslationResultVO batchTranslateArticles(List<String> articleIds, String targetLanguage, boolean updateOriginal) {
        if (CollectionUtils.isEmpty(articleIds)) {
            throw new ServiceException("文章ID列表不能为空");
        }

        if (StringUtils.isBlank(targetLanguage)) {
            throw new ServiceException("目标语言不能为空");
        }

        if (!SUPPORTED_LANGUAGES.containsKey(targetLanguage)) {
            throw new ServiceException("不支持的目标语言: " + targetLanguage);
        }

        // 结果统计
        BatchTranslationResultVO result = new BatchTranslationResultVO();
        result.setTargetLanguage(targetLanguage);
        result.setTotalCount(articleIds.size());
        result.setSuccessCount(0);
        result.setFailCount(0);
        result.setResults(new ArrayList<>());

        // 获取文章列表
        List<VideoArticle> articles = articleMapper.selectBatchIds(articleIds);
        if (CollectionUtils.isEmpty(articles)) {
            throw new ServiceException("未找到有效的文章");
        }

        // 批量处理
        int batchSize = 5; // 每批处理的文章数量

        for (int i = 0; i < articles.size(); i += batchSize) {
            int endIndex = Math.min(i + batchSize, articles.size());
            List<VideoArticle> batch = articles.subList(i, endIndex);

            for (VideoArticle article : batch) {
                BatchTranslationResultVO.TranslationResult translationResult = new BatchTranslationResultVO.TranslationResult();
                translationResult.setId(article.getId());
                translationResult.setOriginalTitle(article.getTitle());

                try {
                    // 先检查是否已有翻译
                    ArticleTranslation existingTranslation = translationMapper.selectByArticleAndLanguage(article.getId(), targetLanguage);

                    if (existingTranslation != null) {
                        // 使用现有翻译
                        translationResult.setSuccess(true);
                        translationResult.setTranslatedTitle(existingTranslation.getTitle());
                        result.setSuccessCount(result.getSuccessCount() + 1);
                    } else {
                        // 翻译标题
                        String translatedTitle = translate(article.getTitle(), targetLanguage);

                        // 翻译描述
                        String translatedDescription = null;
                        if (StringUtils.isNotBlank(article.getDescription())) {
                            translatedDescription = translate(article.getDescription(), targetLanguage);
                        }

                        // 保存翻译结果
                        saveOrUpdateTranslation(article.getId(), targetLanguage, translatedTitle, translatedDescription);


                        if (updateOriginal) {
                            VideoArticle updateArticle = new VideoArticle();
                            updateArticle.setId(article.getId());
                            updateArticle.setTitle(translatedTitle);
                            updateArticle.setDescription(translatedDescription);
                            articleMapper.updateById(updateArticle);
                        }

                        translationResult.setSuccess(true);
                        translationResult.setTranslatedTitle(translatedTitle);
                        result.setSuccessCount(result.getSuccessCount() + 1);
                    }
                } catch (Exception e) {
                    log.error("Translation failed for article {}", article.getId(), e);
                    translationResult.setSuccess(false);
                    translationResult.setMessage(e.getMessage());
                    result.setFailCount(result.getFailCount() + 1);
                }

                result.getResults().add(translationResult);
            }

            // 批处理之间添加短暂延迟，避免API限制
            if (i + batchSize < articles.size()) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }

        return result;
    }

    @Override
    public List<ArticleTranslationVO> getArticleTranslations(String id) {
        // 检查文章是否存在
        VideoArticle article = articleMapper.selectById(id);
        if (article == null) {
            throw new ServiceException("文章不存在");
        }

        // 获取所有翻译版本
        List<ArticleTranslation> translations = translationMapper.selectByArticleId(id);

        // 转换为VO
        return translations.stream()
                .map(translation -> {
                    ArticleTranslationVO vo = new ArticleTranslationVO();
                    vo.setArticleId(translation.getArticleId());
                    vo.setLanguage(translation.getLanguage());
                    vo.setLanguageName(SUPPORTED_LANGUAGES.getOrDefault(translation.getLanguage(),
                            new HashMap<>()).getOrDefault("name", translation.getLanguage()));
                    vo.setTitle(translation.getTitle());
                    vo.setDescription(translation.getDescription());
                    vo.setCreateTime(translation.getCreateTime());
                    vo.setUpdateTime(translation.getUpdateTime());
                    return vo;
                })
                .collect(Collectors.toList());
    }

    @Override
    public void saveOrUpdateTranslation(String articleId, String language, String title, String description) {
        if (!SUPPORTED_LANGUAGES.containsKey(language)) {
            throw new ServiceException("不支持的目标语言: " + language);
        }

        // 检查是否已存在翻译
        ArticleTranslation existingTranslation = translationMapper.selectByArticleAndLanguage(articleId, language);

        if (existingTranslation != null) {
            // 更新现有翻译
            ArticleTranslation updateTranslation = new ArticleTranslation();
            updateTranslation.setId(existingTranslation.getId());
            updateTranslation.setTitle(title);
            updateTranslation.setDescription(description);
            updateTranslation.setUpdateTime(LocalDateTime.now());

            translationMapper.updateById(updateTranslation);
        } else {
            // 创建新翻译
            ArticleTranslation newTranslation = new ArticleTranslation();
            newTranslation.setId(SnowflakeIdGenerator.nextId());
            newTranslation.setArticleId(articleId);
            newTranslation.setLanguage(language);
            newTranslation.setTitle(title);
            newTranslation.setDescription(description);
            newTranslation.setCreateTime(LocalDateTime.now());
            newTranslation.setUpdateTime(LocalDateTime.now());

            translationMapper.insert(newTranslation);
        }
    }

    /**
     * 转换文章为VO
     */
    private ArticleVO convertToVO(VideoArticle article) {
        ArticleVO vo = new ArticleVO();
        BeanUtils.copyProperties(article, vo);

        // 转换状态等字段
        if (article.getStatus() != null) {
            // 转为字符串类型，VO中使用字符串描述
            vo.setStatus(String.valueOf(article.getStatus()));
        }

        if (article.getArticleTimestamp() != null) {
            vo.setArticleTimestamp(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
                    .format(article.getArticleTimestamp()));
        }

        if (article.getCreateTime() != null) {
            vo.setCreateTime(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
                    .format(article.getCreateTime()));
        }

        if (article.getUpdateTime() != null) {
            vo.setUpdateTime(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
                    .format(article.getUpdateTime()));
        }

        return vo;
    }
}